<?php

/*
 * This file is part of the symfony package.
 * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/**
 * sfWidgetFormDate represents a date widget.
 *
 * @package    symfony
 * @subpackage widget
 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
 * @version    SVN: $Id: nlWidgetFormInputAutocomplete.class.php 618 2011-01-20 08:45:48Z sn $
 */
class nlWidgetFormInputAutocomplete extends nlWidgetFormHtml5Input {

  protected $auto_id = null;
  protected $inp_id = null;

  /**
   * @param array $options An array of options
   * @param array $attributes An array of default HTML attributes
   *
   * @see sfWidgetForm
   */
  protected function configure($options = array(), $attributes = array()) {

    parent::configure($options, $attributes);

    $this->addRequiredOption('url');
    $this->addOption('with_id', true);
    $this->addOption('js_params', array());
    $this->addOption('default_value', null);
    $this->addOption('model', null);
    $this->addOption('column', null);
    $this->addOption('method', '__toString');
    $this->addOption('prepend_script', '');
    $this->addOption('append_script', ';');
    $this->addOption('type', 'search');

  }

  public function getJavaScripts() {
    return array_unique(array_merge(array('/nlSymfonyPlugin/js/jquery.autocomplete.js'), parent::getJavaScripts()));
  }

  public function getStylesheets() {
    return array('/nlSymfonyPlugin/css/jquery.autocomplete.css' => 'screen');
  }

  /**
   * Renders the widget.
   *
   * @param  string $name        The element name
   * @param  string $value       The value displayed in this widget
   * @param  array  $attributes  An array of HTML attributes to be merged with the default HTML attributes
   * @param  array  $errors      An array of errors for the field
   *
   * @return string An HTML tag string
   *
   * @see sfWidgetForm
   */
  public function render($name, $value = null, $attributes = array(), $errors = array()) {
    $this->auto_id = $this->generateId($name . '_autocomplete');
    $this->inp_id = $this->generateId($name);

    $generatedHtml = '';

    $attributes = $attributes +
                  array(
                    'type' => $this->getOption('type'),
                    'value' => $this->getDefaultValue($value),
                    'id' => $this->auto_id,
                  );


    if ($this->isRequired()) {
      $attributes = $attributes + array('required' => 'required');
    }
    if ($this->getPattern()) {
      $attributes = $attributes + array('pattern' => $this->getPattern());
    }

    if ($this->getOption('with_id')) {
      $generatedHtml .= $this->renderTag('input', $attributes);
      $generatedHtml .= $this->renderTag('input', array('type' => 'hidden', 'value' => $value, 'name' => $name, 'id' => $this->inp_id) );
      $generatedHtml .= $this->renderScript();
    } else {
      $attributes = $attributes + array(
        'name' => $name
      );

      $generatedHtml .= $this->renderTag('input', $attributes);
      $generatedHtml .= $this->renderScript();
    }


    return $generatedHtml;
    
  }

  public function getDefaultValue($value) {

    if ($this->getOption('default_value') !== null) {
      return $this->getOption('default_value');
    }

    if ($this->getOption('with_id') && $this->getOption('model') !== null && $this->getOption('column') !== null && $value ) {
      return Doctrine_Core::getTable($this->getOption('model'))->findOneBy($this->getOption('column'), $value)->{$this->getOption('method')}();
    }

    return (string)$value;
  }

  private function renderScript() {

    $js = <<< JS
$('#%%auto_id%%').autocomplete('%%url%%', '%%js_params%%')
JS;

    // если рендерим без скрытого id поля.
    if (!$this->getOption('with_id')) {

    } else {
      $js_params = $this->getOption('js_params');

      if (!isset($js_params['onItemSelect']) && $this->auto_id != $this->inp_id) {
        $js_params['onItemSelect'] = <<< JS
$('#%%inp_id%%').val(row.extra[0]);
JS;

        $js_params['onItemSelect'] = 'function(row){' . $js_params['onItemSelect'] . '}';
      };
      $this->setOption('append_script', '.change(function(){if (!$.trim(this.value)) {$("#%%inp_id%%").val(\'\').change();}})' . $this->getOption('append_script'));
    }


    foreach($js_params as $key => $param) {
      $js_params[$key] = "\n". $key.': '.$param;
    }

    $js_params = "{" . "\n". implode(', ', $js_params) . "\n". "}";

    $js = $this->replaceIds(strtr('(function(){' . $this->getOption('prepend_script') . $js .  $this->getOption('append_script') . '})();', array(
        '\'%%js_params%%\'' => $this->replaceIds($js_params),
      )));
    ;



    return $this->renderContentTag('script', $js, array('type' => 'text/javascript'));
  }

  protected function replaceIds($str) {

    return strtr($str, array(
        '%%auto_id%%' => $this->auto_id,
        '%%inp_id%%' => $this->inp_id,
        '%%url%%' => url_for($this->getOption('url'))
      ));
  }
}
